package Model;

import java.util.LinkedList;
import java.util.Stack;

import Controler.MoveBackward;
import Controler.MoveForward;
import Controler.NoMoveBackwardPossible;
import Controler.NoMoveForwardPossible;

public class PlayingField {
	
	private boolean [][] field = null;
	private boolean [][] gameState = null;
	private Stack<MoveForward> recentMovesForward = null;
	private Stack<MoveBackward> recentMovesBackward = null;
	private LinkedList<MoveForward> movesMadeSoFar = null;

	public PlayingField(){
		this.field = new boolean [9][9];
		this.gameState = new boolean [9][9];
		recentMovesForward = new Stack<MoveForward>();
		recentMovesBackward = new Stack<MoveBackward>();
		movesMadeSoFar = new LinkedList<MoveForward>();
		
		for(int y=0;y<9;y++){//this for-loop initializes the Hi-Q-cross
			for(int x=0;x<9;x++){
				if(x>2 && x<6){
					this.field[x][y]=true;
					this.gameState[x][y]=true;
				}
				else if(y>2 && y<6){
					this.field[x][y]=true;
					this.gameState[x][y]=true;
				}
				else{
					this.field[x][y]=false;
					this.gameState[x][y]=false;
				}
//				this.field[4][4]=false;
				this.gameState[4][4]=false;
			}
		}
		
		
		
	}
	
	public void setToXStart(){
		for(int y=0;y<9;y++){
			for(int x=0;x<9;x++){
				this.gameState[x][y]=false;	
			}
		}
		this.gameState[4][2]=true;
		this.gameState[4][3]=true;
		this.gameState[4][4]=true;
		this.gameState[4][5]=true;
		this.gameState[4][6]=true;
		this.gameState[2][4]=true;
		this.gameState[3][4]=true;
		this.gameState[5][4]=true;
		this.gameState[6][4]=true;
	}
	
	public void setToFireplaceStart(){
		for(int y=0;y<9;y++){
			for(int x=0;x<9;x++){
				if(y>4 && y<8 && x>2 && x<6){
					this.gameState[x][y]=true;	
				}
				else{
					this.gameState[x][y]=false;	
				}
				
			}
		}
		this.gameState[3][4]=true;
		this.gameState[5][4]=true;
	}
	
	public void setToPyramidStart(){
		for(int y=0;y<9;y++){
			for(int x=0;x<9;x++){
				if(x>0 && x<8 && y==3){
					this.gameState[x][y]=true;	
				}
				else if(x>1 && x<7 && y==4){
					this.gameState[x][y]=true;
				}
				else if(x>2 && x<6 && y==5){
					this.gameState[x][y]=true;
				}
				else if(x>3 && x<5 && y==6){
					this.gameState[x][y]=true;
				}
				else{
					this.gameState[x][y]=false;	
				}
				
			}
		}
	}
	
	public void setToArrowStart(){
		for(int y=0;y<9;y++){
			for(int x=0;x<9;x++){
				if(x>2 && x<6 && y==1){
					this.gameState[x][y]=true;	
				}
				else if(x>2 && x<6 && y==2){
					this.gameState[x][y]=true;
				}
				else if(x>1 && x<7 && y==5){
					this.gameState[x][y]=true;
				}
				else if(x>2 && x<6 && y==6){
					this.gameState[x][y]=true;
				}
				else{
					this.gameState[x][y]=false;	
				}
				
			}
		}
		this.gameState[4][3]=true;
		this.gameState[4][4]=true;
		this.gameState[4][7]=true;
	}
	
	public void setToDiamondStart(){
		for(int y=0;y<9;y++){
			for(int x=0;x<9;x++){
				if(x>2 && x<6 && y==2){
					this.gameState[x][y]=true;	
				}
				else if(x>1 && x<7 && y==3){
					this.gameState[x][y]=true;
				}
				else if(x>0 && x<8 && y==4){
					this.gameState[x][y]=true;
				}
				else if(x>1 && x<7 && y==5){
					this.gameState[x][y]=true;
				}
				else if(x>2 && x<6 && y==6){
					this.gameState[x][y]=true;
				}
				else{
					this.gameState[x][y]=false;	
				}
				
			}
		}
		this.gameState[4][4]=false;
		this.gameState[4][1]=true;
		this.gameState[4][7]=true;
		
//		this.field[3][0]=false;
//		this.field[4][0]=false;
//		this.field[5][0]=false;
//		this.field[3][8]=false;
//		this.field[4][8]=false;
//		this.field[5][8]=false;
//		this.field[0][3]=false;
//		this.field[0][4]=false;
//		this.field[0][5]=false;
//		this.field[8][3]=false;
//		this.field[8][4]=false;
//		this.field[8][5]=false;
	}
	
	public void setToSmallerCrossStart(){
		
		this.field[3][0]=false;
		this.field[4][0]=false;
		this.field[5][0]=false;
		this.field[3][8]=false;
		this.field[4][8]=false;
		this.field[5][8]=false;
		this.field[0][3]=false;
		this.field[0][4]=false;
		this.field[0][5]=false;
		this.field[8][3]=false;
		this.field[8][4]=false;
		this.field[8][5]=false;
		
		this.gameState[3][0]=false;
		this.gameState[4][0]=false;
		this.gameState[5][0]=false;
		this.gameState[3][8]=false;
		this.gameState[4][8]=false;
		this.gameState[5][8]=false;
		this.gameState[0][3]=false;
		this.gameState[0][4]=false;
		this.gameState[0][5]=false;
		this.gameState[8][3]=false;
		this.gameState[8][4]=false;
		this.gameState[8][5]=false;
	}
	
	public boolean equals1(PlayingField pf){
		
		for(int y=0; y<this.gameState.length; y++){
			for(int x=0; x<this.gameState[0].length; x++){
				if(pf.getGameState()[x][y]!=this.gameState[x][y]){
					return false;			
				}
			}
		}
		return true;
	}
	
//	public void copy(PlayingField pf){
//		this.field=pf.getField();
//		this.gameState=pf.getGameState();
//	}
	
	/**
	 * NOT WORKING YET! CAREFUL!!!
	 * @param x
	 * @param y
	 */
	public PlayingField(int x, int y){
		this.field = new boolean [x][y];
	}
	
	public boolean [][] getField(){
		return this.field;
	}
	
	public boolean [][] getGameState(){
		return this.gameState;
	}
	
	public void setStone(int x, int y, boolean b){
		this.gameState[x][y]=b;
	}
	
	
	/**
	 * only for the 9x9 cross
	 * @return
	 */
	public boolean isSolved(){
		if(this.gameState[4][4]==false){
			return false;
		}
		for(int y=0; y<this.gameState.length; y++){
			for(int x=0; x<this.gameState[0].length; x++){
				if(this.getGameState()[x][y] == true && x!=4 && y!=4){
					return false;			
				}
			}
		}
		return true;
	}
	
	public void setGameState(boolean [][] state){
		for(int y=0;y<state.length;y++){
			for(int x=0;x<state[0].length;x++){
				this.gameState[x][y] = state[x][y];
			}
		}
	}
	
	public Stack<MoveForward> getStackForward(){
		return this.recentMovesForward;
	}
	
	public Stack<MoveBackward> getStackBackward(){
		return this.recentMovesBackward;
	}
	
	public void setStackForward(Stack<MoveForward> st){
		this.recentMovesForward=st;
	}
	
	public void setStackBackward(Stack<MoveBackward> st){
		this.recentMovesBackward=st;
	}
	
	public MoveForward getLastMoveForward(){
		MoveForward result=null;
		if(this.recentMovesForward.isEmpty()){
			try
		    {
		      throw new NoMoveForwardPossible("Stack doesn't contain any forward moves!");
		    }
		    catch(NoMoveForwardPossible e)
		    {			
		      System.out.print(e.getMessage());	
		    }
		}
		else{
			result=recentMovesForward.pop();
			recentMovesForward.push(result);
		}
		return result;
	}
	
	public MoveBackward getLastMoveBackward(){
		if(recentMovesBackward.isEmpty()){
			try
		    {
		      throw new NoMoveBackwardPossible("Stack doesn't contain any Backward moves!");
		    }
		    catch(NoMoveBackwardPossible e)
		    {			
		      System.out.print(e.getMessage());	
		    }
		}
		else{
			MoveBackward result=recentMovesBackward.pop();
			recentMovesBackward.push(result);
			return result;
		}
		return null;
	}
	
	/**
	 * 0 means: Not part of the Game.
	 * 1 means: hole
	 * 2 means: peg
	 * @return
	 */
	public int[][] getThreeStatesPlayingField(){
		
		int [][] result = new int[this.field.length][this.field[0].length];
		for(int y=0;y<this.field[0].length;y++){
			for(int x=0;x<this.field.length;x++){
				if(this.field[x][y]==false){
					result[x][y]=0;
				}
				else if(this.gameState[x][y]==false){
					result[x][y]=1;
				}
				else{
					result[x][y]=2;
				}
			}
		}
		
		
		return result;
	}
	
	public LinkedList<MoveForward> getListWithMovesForward(){
		return this.movesMadeSoFar;
		}
	
	public void setListWithMovesForward(LinkedList<MoveForward> list){
		this.movesMadeSoFar=list;
	}
	
}
